﻿using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System;
using NiuX.InteractiveConsole.Internal;

namespace NiuX.InteractiveConsole.Helpers;

public static class InteractiveConsoleExtensions
{
    public static string WithInteractiveInput(this string message, object defaultValue = default, string placeholder = default, IList<Func<object, ValidationResult>> validators = default)
    {
        return Prompt.Input<string>(options =>
        {
            options.Message = message;
            options.Placeholder = placeholder;
            options.DefaultValue = defaultValue;

            options.Validators.Merge(validators);
        });
    }

    public static T WithInteractiveInput<T>(this string message, object defaultValue = default, string placeholder = default, IList<Func<object, ValidationResult>> validators = default)
    {
        return Prompt.Input<T>(options =>
        {
            options.Message = message;
            options.Placeholder = placeholder;
            options.DefaultValue = defaultValue;

            options.Validators.Merge(validators);
        });
    }

    public static bool WithInteractiveConfirm(this string message, bool? defaultValue = default)
    {
        return Prompt.Confirm(options =>
        {
            options.Message = message;
            options.DefaultValue = defaultValue;
        });
    }

    public static string WithInteractivePassword(this string message, string passwordChar = "*", string placeholder = default, IList<Func<object, ValidationResult>> validators = default)
    {
        return Prompt.Password(options =>
        {
            options.Message = message;
            options.Placeholder = placeholder;
            options.PasswordChar = passwordChar;

            options.Validators.Merge(validators);
        });
    }

    public static T WithInteractiveSelect<T>(this string message, IEnumerable<T> items = default, int? pageSize = default, object defaultValue = default, Func<T, string> textSelector = default)
    {
        return Prompt.Select<T>(options =>
        {
            options.Message = message;
            options.Items = items;
            options.DefaultValue = defaultValue;
            options.PageSize = pageSize;
            options.TextSelector = textSelector;
        });
    }

    public static IEnumerable<T> WithInteractiveMultiSelect<T>(this string message, IEnumerable<T> items = null, int? pageSize = default, int minimum = 1, int maximum = int.MaxValue, IEnumerable<T> defaultValues = default, Func<T, string> textSelector = default)
    {
        return Prompt.MultiSelect<T>(options =>
        {
            options.Message = message;
            options.Items = items;
            options.DefaultValues = defaultValues;
            options.PageSize = pageSize;
            options.Minimum = minimum;
            options.Maximum = maximum;
            options.TextSelector = textSelector;
        });
    }

    public static IEnumerable<T> WithInteractiveList<T>(this string message, int minimum = 1, int maximum = int.MaxValue, IList<Func<object, ValidationResult>> validators = default)
    {
        return Prompt.List<T>(options =>
        {
            options.Message = message;
            options.Minimum = minimum;
            options.Maximum = maximum;

            options.Validators.Merge(validators);
        });
    }

    public static T WithInteractiveBind<T>(this T model) where T : new()
    {
        return Prompt.Bind(model);
    }

}